import { IPSAppDataEntity, IPSAppDEDataSet, IPSSysMap, IPSSysMapItem } from '@ibiz/dynamic-model-api';
import { AppMobMapModel } from '../ctrl-model/app-mob-map-model';
import { ControlServiceBase } from './ctrl-service-base';
import { Util } from '../../util';

/**
 * 地图部件服务对象
 *
 * @export
 * @class AppMobMapService
 */
export class AppMobMapService extends ControlServiceBase {
  /**
   * 表单实例对象
   *
   * @memberof AppMobMapService
   */
  public controlInstance!: IPSSysMap;

  /**
   * 地图配置集合
   *
   * @type {*}
   * @memberof AppMobMapService
   */
  public mapConfig: any[] = [];

  /**
   * 数据服务对象
   *
   * @type {any}
   * @memberof AppMobMapService
   */
  public appEntityService!: any;

  /**
   * 地图项服务集合
   *
   * @type {boolean}
   * @memberof AppMobMapService
   */
  private $itemEntityServiceMap: Map<string, any> = new Map();

  /**
   * 初始化地图项服务集合
   *
   * @type {boolean}
   * @memberof AppMobMapService
   */
  public async initItemEntityService() {
    const calendarItems: Array<IPSSysMapItem> = this.controlInstance.getPSSysMapItems() || [];
    if (calendarItems?.length > 0) {
      for (const item of calendarItems) {
        const codeName = item.getPSAppDataEntity()?.codeName as string;
        if (codeName) {
          const service: any = await App.getEntityService().getService(this.context, codeName.toLowerCase());
          this.$itemEntityServiceMap.set(codeName, service);
        }
      }
    }
  }

  /**
   * 初始化服务参数
   *
   * @type {boolean}
   * @memberof AppMobMapService
   */
  public async initServiceParam() {
    this.appEntityService = await App.getEntityService().getService(this.context, this.appDeCodeName.toLowerCase());
    this.model = new AppMobMapModel(this.controlInstance);
    this.initMapConfig();
  }

  /**
   * 初始化Map参数
   *
   * @memberof AppMobMapService
   */
  public initMapConfig() {
    const mapItems: IPSSysMapItem[] | null = this.controlInstance.getPSSysMapItems();
    if (mapItems) {
      mapItems.forEach((item: IPSSysMapItem, index: number) => {
        this.mapConfig.push({
          itemName: item.name,
          itemType: item.itemType,
          color: item.bKColor,
          textColor: item.color,
          borderColor: item.borderColor,
          borderWidth: item.borderWidth
        });
      });
    }
  }

  /**
   * Creates an instance of AppMobMapService.
   *
   * @param {*} [opts={}]
   * @memberof AppMobMapService
   */
  constructor(opts: any = {}, context?: any) {
    super(opts, context);
    this.controlInstance = opts;
  }

  /**
   * async loaded
   */
  public async loaded() {
    await this.initServiceParam();
  }

  /**
   * 查询数据
   *
   * @param {string} action
   * @param {*} [context={}]
   * @param {*} [data={}]
   * @param {boolean} [isloading]
   * @returns {Promise<any>}
   * @memberof AppMobMapService
   */
  public async search(action: string, context: any = {}, data: any = {}, isloading?: boolean): Promise<any> {
    const mapItems: IPSSysMapItem[] | null = this.controlInstance.getPSSysMapItems();
    if (mapItems?.length != this.$itemEntityServiceMap.size) {
      await this.initItemEntityService();
    }
    return new Promise((resolve: any, reject: any) => {
      const promises: any = [];
      if (mapItems) {
        for (const item of mapItems) {
          const codeName = (item.getPSAppDataEntity() as IPSAppDataEntity)?.codeName || ('' as string);
          const service: any = this.$itemEntityServiceMap.get(codeName);
          const tempRequest: any = this.handleRequestData(action, context, data, true, item.itemType || ('' as string));
          const appDeDataSet: IPSAppDEDataSet = item.getPSAppDEDataSet() as IPSAppDEDataSet;
          if (appDeDataSet.codeName && service[appDeDataSet.codeName]) {
            promises.push(service[appDeDataSet.codeName](tempRequest.context, tempRequest.data, isloading));
          }
        }
      }
      Promise.all(promises)
        .then((resArray: any) => {
          const _data: any = [];
          resArray.forEach((response: any, resIndex: number) => {
            if (!response || response.status !== 200) {
              return;
            }
            const _response: any = JSON.parse(JSON.stringify(response));
            _response.data.forEach((item: any, index: number) => {
              _response.data[index].color =  _response.data[index].color ? _response.data[index].color : this.mapConfig[resIndex].color;
              _response.data[index].textColor = _response.data[index].textColor ? _response.data[index].textColor : this.mapConfig[resIndex].textColor;
              _response.data[index].borderColor = _response.data[index].borderColor ? _response.data[index].borderColor : this.mapConfig[resIndex].borderColor;
              _response.data[index].borderWidth = _response.data[index].borderWidth ? _response.data[index].borderWidth : this.mapConfig[resIndex].borderWidth;
              _response.data[index].curData = Util.deepCopy(item);
              _response.data[index].itemType = this.mapConfig[resIndex].itemType;
            });
            this.handleResponse(action, _response, false, this.mapConfig[resIndex].itemType);
            _data.push(..._response.data);
          });
          const result = { status: 200, data: _data };
          resolve(result);
        })
        .catch((response: any) => {
          reject(response);
        });
    });
  }

  /**
   * 处理request请求数据
   *
   * @param action 行为
   * @param data 数据
   * @memberof AppMobMapService
   */
  public handleRequestData(
    action: string,
    context: any = {},
    data: any = {},
    isMerge: boolean = false,
    itemType: string = '',
  ) {
    const model: any = this.getMode();
    model.itemType = itemType;
    return super.handleRequestData(action, context, data, isMerge);
  }

  /**
   * 处理response返回数据
   *
   * @param {string} action
   * @param {*} response
   * @memberof AppMobMapService
   */
  public async handleResponse(action: string, response: any, isCreate: boolean = false, itemType: string = '') {
    const model: any = this.getMode();
    model.itemType = itemType;
    super.handleResponse(action, response, isCreate);
  }
}
